#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <malloc.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>
#include "parser.h"
#include "runner.h"
#include "err.h"
#include "test.h"
#include "utils.h"




void init(int argc, char **argv)
{
     //init_runner();
    update_env_dir();
    parser_init(argc, argv);
}



void print_greeting()
{
    char *username =  get_env_variable(USER_VARIABLE_NAME),
            *hostname =  get_env_variable(HOST_VARIABLE_NAME),
            *dir =  get_env_variable(PWD_VARIABLE_NAME),
            *home =  get_env_variable(HOME_VARIABLE_NAME);

    if (username == NULL)
        username = strdup("nobody");

    if (hostname == NULL)
        hostname = strdup("localhost");

    if (dir == NULL)
        dir = strdup("invalid_dir");

    if (home != NULL)
    {
        vchar v_dir;
        vchar_init(&v_dir);

        size_t i = 0, len = strlen(dir),
                home_len = strlen(home);
        int8_t indicator = 0;
        while (i < len)
        {
            while (i < len && dir[i] != CATALOG_DELIMETER)
            {
                vchar_append(&v_dir, dir[i]);
                i++;
            }
            if (!indicator && v_dir.str &&
                    !strncmp(v_dir.str , home, home_len * sizeof(char)))
            {
                vchar_clear(&v_dir);
                vchar_append(&v_dir, '~');
                indicator = 1;
            }
            if (i < len)
            {
                vchar_append(&v_dir, CATALOG_DELIMETER);
                i++;
            }
        }
        free(dir);
        dir = v_dir.str;
    }

    char ch = (strncmp(username, "root", 4 * sizeof(char)) == 0) ? '#' : '>';

    printf("%s@%s:%s%c", username, hostname, dir, ch);
    free(dir);
    free(username);
    free(hostname);
    if (home != NULL)
        free(home);
}

int main(int argc, char **argv)
{
    if (argc == 2 && !strncmp(argv[1], "--help", 6 * sizeof(char)))
    {
        print_help();
        return 0;
    }

    if (argc > 1)
    {
        struct stat statbuf;
        if (stat(argv[1], &statbuf))
        {
            print_error(make_error_struct(errno, SHELL_SYSTEM,""));
            return 0;
        }
        init(argc - 1, &argv[1]);
        err_strc res = run_file(argv[1]);
        if (res.errnum != SHELL_NO_ERROR)
            print_error(res);
    }
    else
    {
        init(argc, argv);
        //test_all();
        err_strc sh_err;
        do
        {
            print_greeting();
            sh_err = run_iteration(NULL);
            if (sh_err.errnum != SHELL_QUIT_ERROR && sh_err.errnum != SHELL_NO_ERROR &&
                    !(sh_err.attrib & SHELL_CRITICAL))
                print_error(sh_err);
        }
        while (sh_err.errnum != SHELL_QUIT_ERROR);
    }
    parser_free();
    return 0;

}


